home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 2 / Gekikoh Dennoh Club Vol. 2 (Japan).7z / Gekikoh Dennoh Club Vol. 2 (Japan) (Track 01).bin / tools / post2_g2 / src / p_find.c < prev    next >
Text File  |  1997-10-13  |  13KB  |  578 lines

  1. /*
  2.     post / 郵便番号検索プログラム
  3.  
  4.     p_find.c / 検索部
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "post.h"
  11.  
  12.  
  13. /*
  14.     市区郡存在チェック&抜き出し
  15. */
  16. void
  17. shikugun_check()
  18. {
  19.     int    goukei = 0,    /* 市区郡文字数合計 */
  20.         shiku_num[ 5 ],    /* 入力住所内に市区郡の文字が何文字ずつあるか */
  21.         i1=0, i2=0;    /* ループ汎用 */
  22.  
  23.     /*
  24.         各デリミタ漢字数算出
  25.     */
  26.     for( i1=0; i1<=5-1; ++i1 ) {
  27.         shiku_num[ i1 ] = strschks( input_str, kanji_shiku[ i1 ] );
  28.         goukei += shiku_num[ i1 ];
  29.     }
  30.  
  31.     /*
  32.         市区郡特定
  33.     */
  34.     switch (goukei) {
  35.  
  36.         case 0:
  37.             /* 独自検索を試みる */
  38.             dokuji_kensaku();
  39.  
  40.             break;
  41.  
  42.         case 1:
  43.             if( shiku_num[ 2 ] ) {    /* つまり、「郡」のみ見つかった */
  44.  
  45.                 // 未決。郡のみを検索する。→特Aへ
  46.                 printf("警告 101 : 郡の入力はありましたが、");
  47.                 printf("町村の特定ができませんでした。\n");
  48.                 return;
  49.  
  50.             } else {
  51.                 /* 何にヒットしたのか? */
  52.                 for( i1=0; i1<=5-1; ++i1 ) {
  53.                     if( shiku_num[ i1 ] ) {
  54.                         i2 = i1;
  55.                         break;
  56.                     }
  57.                 }
  58.                 cut_check( i2, -1 );
  59.             }
  60.  
  61.             break;
  62.  
  63.         case 2:
  64.  
  65.             if( shiku_num[ 2 ] && shiku_num[ 3 ] ) {    /* 郡と町 */
  66.                 cut_check( 2, 3 );
  67.  
  68.             } else if( shiku_num[ 2 ] && shiku_num[ 4 ] ) {    /* 郡と村 */
  69.                 cut_check( 2, 4 );
  70.  
  71.             } else if( shiku_num[ 0 ] && shiku_num[ 1 ] ) {    /* 市と区 */
  72.  
  73.                 if( (todo_sw) && (num_pref == 12) ) {
  74.                     cut_check( 1, -1 );    /* 東京に市内区はない */
  75.                 } else {
  76.                     cut_check( 0, 1 );    /* 市内区だ */
  77.                 }
  78.  
  79.             } else {
  80.                 /* 複数可能性を同時チェック */
  81.                 check_kanousei( shiku_num );
  82.             }
  83.  
  84.             break;
  85.  
  86.         default:    /* デリミタが3つ以上検索できた */
  87.  
  88.             /* 複数可能性を同時チェック */
  89.             check_kanousei( shiku_num );
  90.             break;
  91.  
  92.     } /* switch終端 */
  93.  
  94.     return;
  95. }
  96.  
  97.  
  98. /*
  99.     市区郡町村を切り離し&特定
  100.  
  101.     特定できた場合、shiku_tokutei_sw をオン
  102. */
  103. void
  104. cut_check( int kou1, int kou2 )
  105. {
  106.     int    i1,        /* ループ汎用 */
  107.         shima = 0,    /* 島しょ特定用 */
  108.         delim_code,    /* デリミタコード(kou2市内区処理用) */
  109.         toku_sw = 0,    /* 都区かどうか */
  110.         kensuu = 0,    /* 件数カウント */
  111.         point[32],    /* ポイント検索時の ofs 退避 */
  112.         next = 0,    /* 次のオフセットを取るため */
  113.         s_num = 0,    /* 選択肢用 */
  114.         ofs_taihi;    /* オフセット待避用 */
  115.  
  116.     uchar    cc_work[64],    /* キャラクタチェック・ワーク */
  117.         *cc_work_p,    /* cc_work用のポインタ */
  118.         cc_work2[64],    /* del_last_char 対策 */
  119.         tbuf[64],    /* 県/郡確定用ワーク */
  120.         pr_wk[64],    /* 区選択用ワーク */
  121.         *tbuf_p;    /* tbuf用ポインタ */
  122.  
  123.     uchar    numbuff[12];
  124.  
  125.     uchar    ku_kubun[12],        /* 特別区かどうか */
  126.     /* 市内区のみ入力時のプール */
  127.         todouf_p[12][10],    /* 都道府県用 */
  128.         shigun_p[12][64],    /* 市名・郡名用 */
  129.         kutyou_p[12][64],    /* 区名・町村名用 */
  130.     /* 読みも */
  131.         todouf_y[12][10],    /* 都道府県用 */
  132.         shigun_y[12][64],    /* 市名・郡名用 */
  133.         kutyou_y[12][64];    /* 区名・町村名用 */
  134.  
  135.  
  136.     cc_work[0] = '\0';    /* 配列初期化 */
  137.     cc_work_p = cc_work;    /* ポインタ初期化 */
  138.  
  139.     koumoku_set( cc_work_p, kou1 );    /* 項目の特定 */
  140. //    printf("cc_work=|%s|,kou1=%d\n",cc_work,kou1);
  141.  
  142.     if( kou1 == 1 ) {    /* 「区」なら、特別区か市内区かを判定する */
  143.  
  144.         /* 特別区かどうかを調べる */
  145.         toku_sw = 0;
  146.         for( i1=0; i1<=kusuu-1; i1++ ) {
  147.             if( strcmp( cc_work, toku[i1][0] ) == 0 ) {
  148.                 toku_sw = 1;
  149.                 break;
  150.             }
  151.         }
  152.  
  153.         /* デリミタなしで区名を検索、件数をカウント */
  154.         ofs_taihi = ofs;
  155.         ofs = 0;
  156.         kensuu = 0;
  157.         strcpy( cc_work2, cc_work );
  158.         del_last_char( cc_work2 );
  159.         do {
  160.             ofs = bm_find( '.', cc_work2, ofs );
  161.             if( ofs == -1 ) {
  162.                 break;
  163.             }
  164.  
  165.             /* 次がデリミタでない=揃わなかった */
  166.             if( buf[ofs+1] != '+' ) {
  167.                 ofs++;
  168.                 continue;        /* ヒットではない */
  169.             }
  170.  
  171.             next = ofs;    /* 今のオフセットをとっておく */
  172.             pass_back_han( '.' );    /* 直前のデリミタまで戻る */
  173.             if( buf[ ofs-1 ] == '$' || buf[ ofs-1] == '\"' ) {    /* 区なら */
  174.                 /* 記憶しておく */
  175.                 point[ kensuu ] = ofs - 1;    /* デリミタを指している */
  176.                 kensuu++;
  177.             }
  178.             ofs = next;    /* オフセットを戻す */
  179.         } while( 1 );
  180.         ofs = ofs_taihi;
  181.  
  182.         if( kensuu == 0 ) {        /* 該当区名は特別区・市内区にはなかった */
  183.  
  184.             printf("警告 105 : 区名は検索できませんでした。|%s|\n", cc_work );
  185.  
  186.         } else if( kensuu == 1 ) {    /* 1件に絞れた */
  187.  
  188.             if( !toku_sw ) {    /* 特別区ではない */
  189.  
  190.                 ofs = point[0] + 1;
  191.                 next = ofs - 1;
  192.  
  193.                 /* 区名をゲット */
  194.                 get_next_han( shikumei2 );
  195.                 strcat( shikumei2, "区" );
  196.                 get_next_han2( yomi2 );
  197.  
  198.                 /* 直前の市名をゲット */
  199.                 pass_back_han( '!' );
  200.                 get_next_han( shikumei );
  201.                 strcat( shikumei, "市" );
  202.                 get_next_han2( yomi1 );
  203.  
  204.                 kou1 = 1;    /* 市 */
  205.                 kou2 = 5;    /* 市内区 */
  206.  
  207.                 shiku_tokutei_sw = 1;        /* これで確定 */
  208.                 str_purge( cc_work );        /* 入力文字列から削除 */
  209.                 todo_kakutei();            /* 都道府県を確定 */
  210.                 ofs = next;
  211.                 pass_next_han2( '*' );
  212.                 return;
  213.             } else {
  214.  
  215.                 kou1 = 1;
  216.                 kou2 = -1;
  217.             }
  218.  
  219.         } else {            /* 2件以上あった */
  220.  
  221.             for( i1=0; i1<=kensuu-1; i1++ ) {
  222.  
  223.                 ofs = point[i1];    /* デリミタを指している */
  224.  
  225.                 if( buf[ofs] == '\"' ) {    /* 特別区 */
  226.  
  227.                     ofs++;
  228.                     ku_kubun[i1] = 1;
  229.  
  230.                     get_next_han(  shigun_p[i1] );    /* 市郡の方に取る */
  231.                     strcat( shigun_p[i1], "区" );
  232.                     get_next_han2( shigun_y[i1] );
  233.                     strcpy( todouf_p[i1], "東京都" );
  234.                     strcpy( todouf_y[i1], "トウキョウト" );
  235.                     kutyou_p[i1][0] = '\0';
  236.                     kutyou_y[i1][0] = '\0';
  237.  
  238.                 } else {            /* 市内区 */
  239.  
  240.                     ofs++;
  241.                     ku_kubun[i1] = 0;
  242.  
  243.                     /* 区名をゲット */
  244.                     get_next_han( kutyou_p[i1] );
  245.                     strcat( kutyou_p[i1], "区" );
  246.                     get_next_han2( kutyou_y[i1] );
  247.  
  248.                     /* 直前の市名をゲット */
  249.                     pass_back_han( '!' );
  250.                     get_next_han( shigun_p[i1] );
  251.                     strcat( shigun_p[i1], "市" );
  252.                     get_next_han2( shigun_y[i1] );
  253.  
  254.                     /* 都道府県名をゲット */
  255.                     pass_back_han( ' ' );
  256.                     get_next_han(  todouf_p[i1] );
  257.                     get_next_han2( todouf_y[i1] );
  258.                 }
  259.             }
  260.  
  261.             /* 列挙して表示 */
  262.  
  263.             puts("解析の結果、次のような候補を検索することができました。");
  264.             puts("希望する正しい住所を選択して下さい。");
  265.  
  266.             strcpy( pr_wk, cc_work );
  267.             del_last_char( pr_wk );
  268.  
  269.             for( i1=0; i1<=kensuu-1; i1++ ) {
  270.  
  271.                 /* 桁揃え */
  272.                 keta( todouf_y[i1], todouf_p[i1] );
  273.                 keta( shigun_y[i1], shigun_p[i1] );
  274.                 keta( kutyou_y[i1], kutyou_p[i1] );
  275.  
  276.                 printf("%2d :\t", i1+1 );
  277.                 kugiri();
  278.                 printf("%s", todouf_y[i1] );
  279.                 kugiri();
  280.                 printf("%s", shigun_y[i1] );
  281.                 kugiri();
  282.                 if( ku_kubun[i1] == 0 ) {
  283.                     printf("%s", kutyou_y[i1] );
  284.                     kugiri();
  285.                 }
  286.                 puts("");
  287.  
  288.                 printf("\t");
  289.                 kugiri();
  290.                 printf("%s", todouf_p[i1] );
  291.                 kugiri();
  292.                 if( ku_kubun[i1] == 0 ) {
  293.                     printf("%s", shigun_p[i1] );
  294.                     kugiri();
  295.                     moji_pr( kutyou_p[i1], pr_wk ); /* 色付き表示 */
  296.                     kugiri();
  297.                 } else {
  298.                     moji_pr( shigun_p[i1], pr_wk );
  299.                     kugiri();
  300.                 }
  301.                 puts("");
  302.             }
  303.  
  304.             printf("1 から %2d までの数字で選択して下さい : ",kensuu);
  305.  
  306.             do{
  307.                 scanf( "%2s", numbuff );
  308.                 s_num = atoi( numbuff );
  309.             } while ( (s_num < 1) || (s_num > kensuu) );
  310.             puts("");
  311.             /* 入力される番号は、表示を1から始めるため、実際には1多い */
  312.             s_num--;
  313.  
  314.             if( ku_kubun[ s_num ] == 0 ) {    /* 市内区なら */
  315.  
  316.                 strcpy( shikumei2, kutyou_p[ s_num ] );    /* 区名をセット */
  317.                 strcpy( yomi2, kutyou_y[ s_num ] );    /* 区名読み */
  318.                 strcpy( shikumei, shigun_p[ s_num ] );    /* 市名をセット */
  319.                 strcpy( yomi1, shigun_y[ s_num ] );    /* 市名読み */
  320.  
  321.                 kou1 = 1;    /* 市 */
  322.                 kou2 = 5;    /* 市内区 */
  323.                 shiku_tokutei_sw = 1;        /* これで確定 */
  324.                 str_purge( cc_work );        /* 入力文字列から削除 */
  325.                 ofs = point[ s_num ];
  326.                 todo_kakutei();            /* 都道府県を確定 */
  327.                 pass_next_han2( '*' );
  328.                 return;
  329.  
  330.             } else {            /* 特別区なら */
  331.                 /* cut_check でちゃんと処理される */
  332.                 kou1 = 1;
  333.                 kou2 = -1;
  334.             }
  335.         }
  336.     }
  337.  
  338.     if( find_strs_pref( cc_work, kou1 ) ) {
  339.  
  340.         if( todo_sw == 0 ) {    /* 都道府県が確定していなければ確定する */
  341.  
  342.             todo_kakutei();    /* 確定ルーチンへ */
  343.         }
  344.  
  345.         if( (kou1 == 3) || (kou1 == 4) ) {    /* 郡が確定していなければ確定する */
  346.  
  347.             if( num_pref == 12 ) {    /* 東京都なら */
  348.                 /* 島名を特定 */
  349.                 shima = -1;
  350.                 for( i1=0; i1<=tousuu-1; i1++ ) {
  351.                     if( strstr( cc_work, tousyo[i1][0] ) != NULL ) {
  352.                         shima = i1;
  353.                         break;
  354.                     }
  355.                 }
  356.                 if( shima != -1 ) {
  357.                     tousyo_sw = 1;
  358.                 } else {
  359.                     tousyo_sw = 0;
  360.                 }
  361.             }
  362.  
  363.             ofs_taihi = ofs;
  364.  
  365.             tbuf[ 0 ] = '\0';
  366.             tbuf_p = tbuf;
  367.  
  368.             pass_back_han( delim_shiku[ 2 ] );    /* [2]は郡 */
  369.             get_next_han( tbuf_p );        /* 郡名を得る */
  370.             /* 郡名の読みはあとで得る(島しょ対策) */
  371.  
  372.             kou2 = kou1;    /* kou2は町村へ */
  373.             kou1 = 1;    /* kou1は郡へ */
  374.  
  375.             if( tousyo_sw ) {    /* 島しょの場合 */
  376.  
  377.                 strcpy( shikumei, "島しょ" );        /* 郡名はなし */
  378.                 strcpy( yomi1, "トウシヨ" );
  379.  
  380.             } else {
  381.  
  382.                 fuka_delim( tbuf_p, 2 );    /* 「郡」の字を追加 */
  383.                 strcpy( shikumei, tbuf );
  384.                 get_next_han2( yomi1 );        /* 郡の読みを得る */
  385.             }
  386.  
  387.             /* いまofsは町名の直後にいるので補正 */
  388.             ofs = ofs_taihi - (strlen( tbuf ) + 1);
  389.             get_next_han2( yomi2 );        /* 町村名の読みを得る */
  390.  
  391.         } else {
  392.  
  393.             strcpy( shikumei, cc_work );    /* 市区名ワークへコピー */
  394.             str_purge( cc_work );        /* 入力文字列から市区名を削除 */
  395.             get_next_han2( yomi1 );        /* 市区名の読みを得る */
  396.         }
  397.  
  398.  
  399.         /* 郡+町村または市+市内区の処理 */
  400.         if( kou2 != -1 ) {
  401.  
  402.             cc_work[0] = '\0';    /* 配列初期化 */
  403.             cc_work_p = cc_work;    /* ポインタ初期化 */
  404.  
  405.             koumoku_set( cc_work_p, kou2 );    /* 項目の特定 */
  406.  
  407.             if( kou2 == 1 ) {    /* 市内区なら */
  408.                 delim_code = 5;    /* 市内区デリミタコードをセット */
  409.             } else {
  410.                 delim_code = kou2;    /* たぶん郡だが */
  411.             }
  412.  
  413.             if( find_strs_kou2( cc_work, delim_code ) ) {    /* 市内区か町村 */
  414.  
  415.                 strcpy( shikumei2, cc_work );    /* 市区名ワーク2へコピー */
  416.                 str_purge( cc_work );    /* 入力文字列から市区名2を削除 */
  417.                 get_next_han2( yomi2 );    /* 読みを得る */
  418.  
  419.                 if( tousyo_sw ) {        /* 島しょなら */
  420.                     strcpy( shikumei, "" );    /* 郡名なしで */
  421.                     strcpy( yomi1, "" );    /* 読みもなし */
  422.                 }                /* なんか五七五だな */
  423.  
  424.             } else {    /* 市・郡はうまくいったが区・町村でこけた */
  425. printf("delim_code=|%d|, delim=|%c|\n",delim_code, delim_shiku[delim_code] );
  426. //                shima = -1;
  427. //                for( i1=0; i1<=tousuu-1; i1++ ) {
  428. //                    if( strstr( cc_work, tousyo[i1][0] ) != NULL ) {
  429. //                        shima = i1;
  430. //                        break;
  431. //                    }
  432. //                }
  433.  
  434. //                if( shima != -1 ) {    /* 島しょなら */
  435. //@@
  436.  
  437.                 // 未決。市区町村を選ばせる
  438.  
  439.                 printf("警告 102 : 市内区または");
  440.                 printf("町村の検索に失敗しました。 : |%s|\n",cc_work);
  441.                 return;
  442.             }
  443.  
  444.         } else {
  445.  
  446.             if( (kou1 == 0) && (check_next_delim(1) ) ) {
  447.  
  448.                 // 未決。市内区を選ばせる
  449.                 printf("警告 103 : たぶん市内区の入力が抜けています。\n");
  450.                 return;
  451.             }
  452.  
  453.             shikumei2[ 0 ] = '\0';        /* 市区名2はない */
  454.  
  455.         } /* kou2判定if終端 */
  456.  
  457.         shiku_tokutei_sw = 1;
  458.  
  459.     } else {
  460.  
  461.         /* ここに来るのは、入力間違いなど */
  462.  
  463.         if( !dokuji_sw ) {    /* 独自検索でなければ */
  464.  
  465.             dokuji_kensaku();    /* 独自検索してみる */
  466.  
  467.         } else {
  468.  
  469.             printf("警告 104 : 市町村が検索できませんでした。");
  470.             printf(": |%d|%s|\n",kou1,cc_work);
  471.             return;
  472.  
  473.         }
  474.  
  475.     } /* find_strs_prefのif終端 */
  476.  
  477.     return;
  478. }
  479.  
  480.  
  481. /*
  482.     post.datの中から引数cc_workを検索する 市区郡用
  483.  
  484.     引数    cwork        : 探す文字列(市区郡名)
  485.         delim_code    : 探す文字列デリミタ
  486.  
  487.     戻り値    (int)    : 合致すれば1 しなければ0
  488. */
  489. int
  490. find_strs_pref( uchar *cwork, int delim_code )
  491. {
  492.     uchar    read_str[256];    /* 読み出し文字列ワーク */
  493.  
  494.     read_str[ 0 ] = '\0';
  495.  
  496.     ken_atamadashi();
  497.  
  498.     ofs = pref_ofs;
  499.  
  500.     strcpy( read_str, cwork );    /* ワークにコピー */
  501.     del_last_char( read_str );    /* 最終文字(=市とか区とか)を削除 */
  502.  
  503.     while( 1 ) {
  504.         ofs = bm_find( delim_shiku[delim_code], read_str, ofs );
  505.  
  506.         /* 終端か、      きっちり揃ったか */
  507.         if( (ofs == -1) || (check_next_delim(0)) ) {
  508.             break;
  509.         }
  510.     }
  511.  
  512.     return (ofs == -1) ? 0 : 1;
  513.  
  514. }
  515.  
  516.  
  517. /*
  518.     post.datの中から引数cworkを検索する 市内区・町村用
  519.  
  520.     引数    cwork        : 探す文字列(市区郡名)
  521.         delim_code    : 探す文字列デリミタ
  522.  
  523.     戻り値    (int)    : 合致すれば1 しなければ0
  524. */
  525. int
  526. find_strs_kou2( uchar *cwork, int delim_code )
  527. {
  528.     int    ret_val = 0;    /* 戻り値用 */
  529.     uchar    read_wk,    /* 読み出しワーク */
  530.         read_str[256],    /* 読み出し文字列ワーク */
  531.         *read_str_p;    /* 読み出し文字列ポインタ */
  532.  
  533.     /* オフセットを戻す */
  534.     ofs -= ( strlen(shikumei)+1 );
  535.  
  536.     while( 1 ) {
  537.  
  538.         read_wk = buf[ ofs++ ];        /* 一文字取得 */
  539.  
  540.         if( is_not_delim( read_wk ) ) {
  541.             continue;    /* デリミタ文字列でない */
  542.         }
  543.  
  544.         if( read_wk == delim_shiku[ delim_code ] ) {    /* デリミタ一致 */
  545.  
  546.             read_str[ 0 ] = '\0';    /* 初期化 */
  547.             read_str_p = read_str;    /* ポインタセット */
  548.  
  549.             *read_str_p++ = buf[ ofs++ ];    /* 漢字の前半分を取得 */
  550.             if( read_str[ 0 ] != cwork[ 0 ] ) {    /* 前半分比較 */
  551.                 continue;
  552.             }
  553.             *read_str_p++ = buf[ ofs++ ];    /* 漢字の後半分を取得 */
  554.  
  555.             if( read_str[ 1 ] == cwork[ 1 ] ) {    /* 後半分比較 */
  556.                 get_next_han( read_str_p );    /* 次の半角文字までを得る */
  557.  
  558.                 /* トークンに合わせて「市区町村」を付加 */
  559.                 fuka_delim( read_str_p, delim_code );
  560.                 if( strcmp( cwork, read_str ) == 0 ) {    /* 合うか? */
  561.                     ret_val = 1;
  562.                     break;
  563.                 }
  564.             } else {
  565.                 continue;
  566.             }
  567.  
  568.         } else if( (read_wk == '#') || (read_wk == '!') ) { /* 市か郡である */
  569.  
  570.             break;    /* 終わり */
  571.  
  572.         } /* デリミタ判定終端 */
  573.  
  574.     } /* while終端 */
  575.  
  576.     return ret_val;
  577. }
  578.